////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Filename:    CrystalWatersGuts.h	     								  //
//  Developer:   Ryan Sauls												      //
//  Create date: 7/8/2006                                                     //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Description: This is the class declaration for the slot gut of the        //
//               Australian Slot machine called Crystal Waters.               //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
//        Copyright (c) 2006 - Realtime Gaming.  All rights reserved.         //
////////////////////////////////////////////////////////////////////////////////

#pragma once
#include "slotguts.h"
#include "getrand.h"

class CrystalWatersGuts :
	public SlotGuts
{
	typedef SlotGuts super;

public:
	#pragma region Construction & Destruction

	CrystalWatersGuts(void);
	virtual ~CrystalWatersGuts(void);
	
	#pragma endregion

private:
	#pragma region Shared enums between client and server
		#include "CrystalWatersCommon.h"
	#pragma endregion

	#pragma region Private Enums

		enum
		{
			VALID_GUTS_RANGE_BEGIN	= 2600,
			VALID_GUTS_RANGE_END	= 2699
		};

	#pragma endregion

	#pragma region Helpful lookup arrays.

		static SpinResult m_aLineWinSpinResults[NUM_VALID_ICONS][6];

		static SpinResult m_aScatterWinSpinResults[6];

	#pragma region Inline functions to use with the arrays that also do bounds checking.

		static SpinResult lookupLineWinSpinResult( uint8 nIconType, uint8 nCount )
		{
			if ( nIconType < NUM_VALID_ICONS && nCount < 6 )
			{
				return m_aLineWinSpinResults[ nIconType ][ nCount ];
			}

			ASSERT( false );
			return EVT_INVALID;
		}

		static SpinResult lookupScatterWinSpinResult( uint8 nCount )
		{
			if ( nCount < 6 )
			{
				return m_aScatterWinSpinResults[ nCount ];
			}

			ASSERT( false );
			return EVT_INVALID;
		}

		static uint8 getFreeSpinMultiplierNoteId( uint8 nMultiplier )
		{
			if ( nMultiplier == 2 )
			{
				return NOTE_2X_BONUS_FISH;
			}
			else if ( nMultiplier == 4 )
			{
				return NOTE_4X_BONUS_FISH;
			}
			else if ( nMultiplier == 8 )
			{
				return NOTE_8X_BONUS_FISH;
			}
			ASSERT( false );
			return 0;
		}

		uint8 getCurrentFishMultiplier()
		{
			uint8 nRV = m_subGame->getData( SGDIDX_CURRENT_MULTIPLIER );
			return nRV;
		}

		void setCurrentFishMultiplier( uint8 nMultiplier )
		{
			m_subGame->update( SGDIDX_CURRENT_MULTIPLIER, nMultiplier );
		}

	#pragma endregion

	#pragma endregion

protected:

	#pragma region Methods

		SpinResult		getLineWinResult( uint8* stops, uint8 testIcon, 
											bool& bDolphinSubstitution /*out value*/, 
											bool& bBonusFishSubstitution /*out value*/ );

		void			tryForJackpot(SlotSpin* spin);
		void			evaluateScatterWin(SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions);
		void			evaluateFeatureTrigger(SlotSpin* spin, SpinResult srScatterResult, int32 scatterPositions, uint8 numScatterIcons);
		SpinResult		getScatterWinResult(SlotSpin* spin, int32& scatterPositions, uint8& numScatterIcons) const;


	#pragma endregion

	#pragma region Overridden Virtual Methods
		virtual bool8	isValidGuts();	
		virtual void	preSpinClassifyResults( SlotSpin* spin );
		virtual void	classifyStops( SpinLine* spinline, uint8* stops, uint8 bet, uint8 line, uint8& rtnresult, uint8& multiplier );
		virtual void	classifyScatters( SlotSpin *spin );
		virtual void	Debug_SetLoserStops( uint8* pStops );
	
	#pragma region Debug Spins Support
		enum
		{
			EVT_DEBUG_FUNCTION_WIN_RANDOM = BEGIN_SUB_MODIFY_NEXT_RESULT_FUNCTION_RANGE,
			EVT_DEBUG_FUNCTION_WIN_TWO,
			EVT_DEBUG_FUNCTION_WIN_FOUR,
			EVT_DEBUG_FUNCTION_WIN_EIGHT,
		};

		virtual void initDebugFunctionMap();
		void DebugFeature_WinRandom( SlotSpin *spin );
		void DebugFeature_WinTwo( SlotSpin *spin );
		void DebugFeature_WinFour( SlotSpin *spin );
		void DebugFeature_WinEight( SlotSpin *spin );
	#pragma endregion

	#pragma endregion

};
